﻿# -*- coding: utf-8 -*-


import wx
import wx.aui

if wx.Platform == '__WXMSW__':
  """
  wxPython写的,类似Maxthon风格的分页浏览器，使用IE内核。  
  """
  import wx.lib.iewin as iewin

  TBFLAGS = ( wx.TB_HORIZONTAL
  | wx.NO_BORDER
  | wx.TB_FLAT
  #| wx.TB_TEXT
  #| wx.TB_HORZ_LAYOUT
  )


class TestSearchCtrl(wx.SearchCtrl):
  """ This is a SearchCtrl , could keep history search keywords automaticly """

  maxSearches = 10 # number of history search keywords keep in list

  def __init__(self, parent, id=-1, value="",
    pos=wx.DefaultPosition, size=wx.DefaultSize, style=0,
    doSearch=None):
    style |= wx.TE_PROCESS_ENTER
    wx.SearchCtrl.__init__(self, parent, id, value, pos, size, style)
    self.Bind(wx.EVT_TEXT_ENTER, self.OnTextEntered)
    self.Bind(wx.EVT_MENU_RANGE, self.OnMenuItem, id=1, id2=self.maxSearches)
    self.doSearch = doSearch
    self.searches = []

  def OnTextEntered(self, evt):
    text = self.GetValue()
    if len(text) >= 1:
      if self.doSearch(text):
        self.searches.append(text)
    if len(self.searches) > self.maxSearches:
      del self.searches[0]
      self.SetMenu(self.MakeMenu())
      self.SetValue("")
    else:
      msg = (u"请输入网址")
      dlg = wx.MessageDialog(self, msg, u"多窗口浏览器",
      wx.OK | wx.ICON_INFORMATION)
      dlg.ShowModal()
      dlg.Destroy()


  def OnMenuItem(self, evt):
    text = self.searches[evt.GetId()-1]
    self.doSearch(text)

  def MakeMenu(self):
    menu = wx.Menu()
    item = menu.Append(-1, u"Recent Searches")
    item.Enable(False)
    for idx, txt in enumerate(self.searches):
      menu.Append(1+idx, txt)
    return menu


class ParentFrame(wx.aui.AuiMDIParentFrame):
  def __init__(self, parent):
    wx.aui.AuiMDIParentFrame.__init__(self, parent, -1,
    title=u"IC Easy Search Tool",
    size=(640,480),
    style=wx.DEFAULT_FRAME_STYLE)
    self.count = 0
    mb = self.MakeMenuBar()
    self.SetMenuBar(mb)
    self.CreateStatusBar()

    ## Make toolBar ##
    tsize = (16,16)
    new_bmp = wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, tsize)
    open_bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize)
    copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize)
    paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize)
    search_bmp=wx.ArtProvider.GetBitmap(wx.ART_FIND, wx.ART_TOOLBAR, tsize)
    goback_bmp=wx.ArtProvider.GetBitmap(wx.ART_GO_BACK, wx.ART_TOOLBAR, tsize)
    goforward_bmp=wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD, wx.ART_TOOLBAR, tsize)

    tb = self.CreateToolBar( TBFLAGS )
    tb.SetToolBitmapSize(tsize)

    tb.AddSeparator()

    tb.AddLabelTool(10, u"New", new_bmp, shortHelp="New", longHelp="Long help for 'New'")
    self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)
    self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10)

    tb.AddLabelTool(20, u"back", goback_bmp, shortHelp="back", longHelp="Long help for 'back'")
    self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)
    self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20)

    tb.AddLabelTool(30, u"goforward_bmp", goforward_bmp, shortHelp="Foward", longHelp="Long help for 'Foward'")
    self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30)
    self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30)

    tb.AddSeparator()

    self.search = TestSearchCtrl(tb, size=(150,-1), doSearch=self.DoSearch)
    tb.AddControl(self.search)

    # Search button
    tb.AddSimpleTool(50,search_bmp, u"Search","Start Search")
    self.Bind(wx.EVT_TOOL, self.OnToolClick, id=50)
    self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=50)
    tb.AddSeparator()


    # Final thing to do for a toolbar is call the Realize() method. This
    # causes it to render (more or less, that is).
    tb.Realize()



  def MakeMenuBar(self):
    mb = wx.MenuBar()
    menu = wx.Menu()
    item = menu.Append(-1, u"New child window\tCtrl-N")
    self.Bind(wx.EVT_MENU, self.OnNewChild, item)
    item = menu.Append(-1, u"Close parent")
    self.Bind(wx.EVT_MENU, self.OnDoClose, item)
    mb.Append(menu, u"&File")
    return mb

  def OnNewChild(self, evt):
    self.count += 1
    child = ChildFrame(self, self.count)
    child.Browser("http://www.google.com")
    child.Show()

  def OnDoClose(self, evt):
    self.Close()


  def DoSearch(self, text):
    # called by TestSearchCtrl

    # call ActivexIE
    self.count += 1
    child = ChildFrame(self, self.count)
    child.onBrowser(text)
    child.Show()
    # return true to tell the search ctrl to remember the text
    return True


  def OnToolClick(self, event):
    ## self.log.WriteText("tool %s clicked\n" % event.GetId())
    #tb = self.GetToolBar()
    tb = event.GetEventObject()
    #wx.EVT_TEXT_ENTER
    if event.GetId() == 50:
      # press the "Search" button
      self.search.OnTextEntered(event)
    elif event.GetId() == 10:
      #new Child window
      self.OnNewChild(event)


  def OnToolRClick(self, event):
    self.log.WriteText("tool %s right-clicked\n" % event.GetId())




  #----------------------------------------------------------------------

class ChildFrame(wx.aui.AuiMDIChildFrame):
    def __init__(self, parent, count):
      wx.aui.AuiMDIChildFrame.__init__(self, parent, -1,
      title="Child: %d" % count)
      mb = parent.MakeMenuBar()
      menu = wx.Menu()
      item = menu.Append(-1, "This is child %d's menu" % count)
      mb.Append(menu, u"浏览器(&B)")
      self.SetMenuBar(mb)

      ##self.p = wx.Panel(self)
      ##wx.StaticText(self.p, -1, "This is child %d" % count, (10,10))
      ##self.p.SetBackgroundColour('light blue')

      ##sizer = wx.BoxSizer()
      ##sizer.Add(self.p, 1, wx.EXPAND)
      ##self.SetSizer(sizer)

      self.current = "about:blank"
      self.frame = frame

      if frame:
        self.titleBase = frame.GetTitle()

      sizer = wx.BoxSizer(wx.VERTICAL)
      btnSizer = wx.BoxSizer(wx.HORIZONTAL)

      self.ie = iewin.IEHtmlWindow(self, -1, style = wx.NO_FULL_REPAINT_ON_RESIZE)


      btn = wx.Button(self, -1, u"打开", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnOpenButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      btn = wx.Button(self, -1, u"主页", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnHomeButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      btn = wx.Button(self, -1, u"<--", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnPrevPageButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      btn = wx.Button(self, -1, u"-->", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnNextPageButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      btn = wx.Button(self, -1, u"停止", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnStopButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      ## btn = wx.Button(self, -1, "Search", style=wx.BU_EXACTFIT)
      ## self.Bind(wx.EVT_BUTTON, self.OnSearchPageButton, btn)
      ## btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      btn = wx.Button(self, -1, u"刷新", style=wx.BU_EXACTFIT)
      self.Bind(wx.EVT_BUTTON, self.OnRefreshPageButton, btn)
      btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)

      txt = wx.StaticText(self, -1, "Location:")
      btnSizer.Add(txt, 0, wx.CENTER|wx.ALL, 2)

      self.location = wx.ComboBox(
      self, -1, "", style=wx.CB_DROPDOWN|wx.PROCESS_ENTER
      )

      self.Bind(wx.EVT_COMBOBOX, self.OnLocationSelect, self.location)
      self.location.Bind(wx.EVT_KEY_UP, self.OnLocationKey)
      self.location.Bind(wx.EVT_CHAR, self.IgnoreReturn)
      btnSizer.Add(self.location, 1, wx.EXPAND|wx.ALL, 2)

      sizer.Add(btnSizer, 0, wx.EXPAND)
      sizer.Add(self.ie, 1, wx.EXPAND)

      self.ie.LoadUrl(self.current)
      self.location.Append(self.current)

      self.SetSizer(sizer)
      # Since this is a wxWindow we have to call Layout ourselves
      self.Bind(wx.EVT_SIZE, self.OnSize)

      # Hook up the event handlers for the IE window
      self.Bind(iewin.EVT_BeforeNavigate2, self.OnBeforeNavigate2, self.ie)
      self.Bind(iewin.EVT_NewWindow2, self.OnNewWindow2, self.ie)
      self.Bind(iewin.EVT_DocumentComplete, self.OnDocumentComplete, self.ie)
      ##self.Bind(iewin.EVT_ProgressChange, self.OnProgressChange, self.ie)
      self.Bind(iewin.EVT_StatusTextChange, self.OnStatusTextChange, self.ie)
      self.Bind(iewin.EVT_TitleChange, self.OnTitleChange, self.ie)


      wx.CallAfter(self.Layout)

    def ShutdownDemo(self):
      # put the frame title back
      if self.frame:
        self.frame.SetTitle(self.titleBase)


    def OnSize(self, evt):
      self.Layout()


    def OnLocationSelect(self, evt):
      url = self.location.GetStringSelection()
      self.log.write('OnLocationSelect: %s\n' % url)
      self.ie.Navigate(url)

    def OnLocationKey(self, evt):
      if evt.GetKeyCode() == wx.WXK_RETURN:
        URL = self.location.GetValue()
        self.location.Append(URL)
        self.ie.Navigate(URL)
      else:
        evt.Skip()


    def IgnoreReturn(self, evt):
      if evt.GetKeyCode() != wx.WXK_RETURN:
        evt.Skip()

    def OnOpenButton(self, event):
      dlg = wx.TextEntryDialog(self, u"打开URL",
      u"输入网址或本地路径",
      self.current, wx.OK|wx.CANCEL)
      dlg.CentreOnParent()

      if dlg.ShowModal() == wx.ID_OK:
        self.current = dlg.GetValue()
        self.ie.Navigate(self.current)

      dlg.Destroy()

    def OnHomeButton(self, event):
      self.ie.GoHome() ## ET Phone Home!

    def OnPrevPageButton(self, event):
      self.ie.GoBack()

    def OnNextPageButton(self, event):
      self.ie.GoForward()

    def OnStopButton(self, evt):
      self.ie.Stop()

      ## def OnSearchPageButton(self, evt):
      ## self.ie.GoSearch()

    def OnRefreshPageButton(self, evt):
      self.ie.Refresh(iewin.REFRESH_COMPLETELY)


    def logEvt(self, evt):
      pst = ""
      for name in evt.paramList:
        pst += " %s:%s " % (name, repr(getattr(evt, name)))


    def OnBeforeNavigate2(self, evt):
      #self.logEvt(evt)
      return
    def OnNewWindow2(self, evt):
      #self.logEvt(evt)
      # Veto the new window. Cancel is defined as an "out" param
      # for this event. See iewin.py
      evt.Cancel = True

    def OnProgressChange(self, evt):
      #self.logEvt(evt)
      return

    def OnDocumentComplete(self, evt):
      #self.logEvt(evt)
      self.current = evt.URL
      self.location.SetValue(self.current)

    def OnTitleChange(self, evt):
      #self.logEvt(evt)
      if self.frame:
        self.frame.SetTitle(self.titleBase + ' -- ' + evt.Text)

    def OnStatusTextChange(self, evt):
      #self.logEvt(evt)
      ## if self.frame:
      ## self.frame.SetStatusText(evt.Text)
      return

    def onBrowser(self, url="about:blank"):

      """ Use ActivexIE Ctrl browser the url"""
      self.current = url
      self.location.SetValue(self.current)
      self.ie.LoadUrl(self.current)
      self.location.Append(self.current)

      # End of Child Frame #



class PySimpleApp(wx.App):

  def __init(self, redirect = False, filename=None, useBestVisual = False, clearSigInt = True):
    wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

  def OnInit(self):
    return True


if __name__ == '__main__':
  # Main APP
  app = wx.PySimpleApp(None,-1)
  # Main Frame
  frame = ParentFrame(parent=None)
  frame.Show()
  app.MainLoop()
